package host

import (
	"net/http"
	"strconv"

	"github.com/imdario/mergo"
)

/*

一、不同厂商
1、aliyun
2、tecent
3、aws


二、主机有两个属性
1、公共资源描述
2、详情页描述


三、定义接口方法
*/

const (
	PrivateIDC Vendor = iota
	Aliyun
	Tencent
	Aws
	Huawei
)

type Vendor int

type Host struct {
	*Resource
	*Describe
}

// 对象的局部更新
func (h *Host) Patch(obj *Host) error {
	// if obj.Name != "" {
	// 	h.Name = obj.Name
	// }
	// if obj.CPU != 0 {
	// 	h.CPU = obj.CPU
	// }
	// 比如 obj.A  obj.B  只想修改obj.B该属性
	return mergo.MergeWithOverwrite(h, obj)
}

func Newhost() *Host {

	return &Host{
		Resource: &Resource{},
		Describe: &Describe{},
	}
}

type Resource struct {
	Id          string `json:"id"  validate:"required"`     // 全局唯一Id
	Vendor      Vendor `json:"vendor"`                      // 厂商
	Region      string `json:"region"  validate:"required"` // 地域
	CreateAt    int64  `json:"create_at"`                   // 创建时间
	ExpireAt    int64  `json:"expire_at"`                   // 过期时间
	Type        string `json:"type"  validate:"required"`   // 规格
	Name        string `json:"name"  validate:"required"`   // 名称
	Description string `json:"description"`                 // 描述
	Status      string `json:"status"`                      // 服务商中的状态                     // 标签
	UpdateAt    int64  `json:"update_at"`                   // 更新时间
	SyncAt      int64  `json:"sync_at"`                     // 同步时间
	Account     string `json:"accout"`                      // 资源的所属账号
	PublicIP    string `json:"public_ip"`                   // 公网IP
	PrivateIP   string `json:"private_ip"`                  // 内网IP
}

type Describe struct {
	CPU          int    `json:"cpu" validate:"required"`    // 核数
	Memory       int    `json:"memory" validate:"required"` // 内存
	GPUAmount    int    `json:"gpu_amount"`                 // GPU数量
	GPUSpec      string `json:"gpu_spec"`                   // GPU类型
	OSType       string `json:"os_type"`                    // 操作系统类型，分为Windows和Linux
	OSName       string `json:"os_name"`                    // 操作系统名称
	SerialNumber string `json:"serial_number"`              // 序列号
}

type HostSet struct {
	Total int64   `json:"total" `
	Items []*Host `json:"items"`
}

func NewHostSet() *HostSet {

	return &HostSet{}
}

func NewQueryHostsRequestFromHttp(r *http.Request) *QueryHostsRequest {

	queryHostsRequest := NewQueryHostsRequest()

	res := r.URL.Query()
	page_size := res.Get("page_size")

	page_number := res.Get("page_number")

	if page_number != "" || page_size != "" {
		pgs, _ := strconv.Atoi(page_size)
		pgn, _ := strconv.Atoi(page_number)

		queryHostsRequest.Name = res.Get("name")
		queryHostsRequest.Description = res.Get("description")
		queryHostsRequest.PublicIP = res.Get("public_ip")
		queryHostsRequest.PageNumber = pgn
		queryHostsRequest.PageSize = pgs
	}

	return queryHostsRequest
}

type QueryHostsRequest struct {
	Name        string `json:"name" form:"name" validate:"required"`
	Description string `json:"description" form:"description" `
	PublicIP    string `json:"public_ip" form:"public_ip" `
	PageNumber  int    `json:"page_number" form:"page_number" validate:"required"`
	PageSize    int    `json:"page_size" form:"page_size" validate:"required"`
	// Email       string `json:"email" form:"email" validate:"required,email"` //
}

func NewQueryHostsRequest() *QueryHostsRequest {
	return &QueryHostsRequest{}
}

func NewQueryDescribeHostFromHttp(req *http.Request) *DescribeHostRequest {

	describe := NewDescribeHostRequest()

	query := req.URL.Query()

	if query.Get("id") != "" {
		describe.ID = query.Get("id")
	} else {
		return nil
	}

	return describe
}

type DescribeHostRequest struct {
	ID string `uri:"id" binding:"required"`
}

func NewDescribeHostRequest() *DescribeHostRequest {

	return &DescribeHostRequest{}
}

type UpdatePatchHostRequest struct {
	ID     string `uri:"id" binding:"required"`
	Name   string `json:"name" `
	Region string `json:"region"  ` // 地域
	CPU    int    `json:"cpu" `     // 核数
	Memory int    `json:"memory" `  // 内存
}

func NewUpdatePatchHostRequest() *UpdatePatchHostRequest {
	return &UpdatePatchHostRequest{}
}

type UpdatePutHostRequest struct {
	*Host
}

func NewUpdatePutHostRequest() *UpdatePutHostRequest {
	return &UpdatePutHostRequest{}
}

type DeleteHostRequest struct {
	ID string `uri:"id" binding:"required"`
}

func NewDeleteHostRequest() *DeleteHostRequest {
	return &DeleteHostRequest{}
}
